1 /* 2 * The MIT License (MIT) 3 * 4 * Copyright (c) 2014 Devisualization (Richard Andrew Cattermole) 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in all 14 * copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 */ 24 module devisualization.window.context.opengl; 25 import devisualization.window.window; 26 import devisualization.window.interfaces.context; 27 28 import derelict.opengl3.gl; 29 import derelict.opengl3.wgl; 30 import derelict.opengl3.wglext; 31 32 private { 33 bool loadedDGL; 34 } 35 36 class OpenglContext : IContext { 37 private { 38 HDC hdc_; 39 HGLRC hglrc_; 40 } 41 42 this(Window window, WindowConfig config) { 43 if (!loadedDGL) { 44 DerelictGL.load(); 45 loadedDGL = true; 46 } 47 48 import windows : GetDC; 49 hdc_ = GetDC(window.hwnd); 50 51 configurePixelFormat(window, config, hdc_); 52 53 hglrc_ = cast(HGLRC)wglCreateContext(hdc_); 54 activate(); 55 } 56 57 @property { 58 void activate() { 59 wglMakeCurrent(hdc_, hglrc_); 60 DerelictGL.reload(); 61 } 62 63 void destroy() { 64 wglDeleteContext(hglrc_); 65 } 66 67 void swapBuffers() { 68 glFlush(); 69 SwapBuffers(hdc_); 70 } 71 72 WindowContextType type() { return WindowContextType.Opengl; } 73 74 string toolkitVersion() { 75 char[] str; 76 const(char*) c = glGetString(GL_VERSION); 77 size_t i; 78 79 if (c !is null) { 80 while (c[i] != '\0') { 81 str ~= c[i]; 82 i++; 83 } 84 } 85 86 return str.idup; 87 } 88 89 string shadingLanguageVersion() { 90 char[] str; 91 const(char*) c = glGetString(GL_SHADING_LANGUAGE_VERSION); 92 size_t i; 93 94 if (c !is null) { 95 while (c[i] != '\0') { 96 str ~= c[i]; 97 i++; 98 } 99 } 100 101 return str.idup; 102 } 103 104 string[] extensions() { 105 string[] ret; 106 107 char[] str; 108 const(char*) c = glGetString(GL_SHADING_LANGUAGE_VERSION); 109 size_t i; 110 111 if (c !is null) { 112 while (c[i] != '\0') { 113 if (c[i] == ' ') { 114 ret ~= str.idup; 115 str.length = 0; 116 } else { 117 str ~= c[i]; 118 } 119 i++; 120 } 121 } 122 123 return ret; 124 } 125 } 126 } 127 128 private { 129 import windows : SwapBuffers, HDC, HGLRC; 130 131 void configurePixelFormat(Window window, WindowConfig config, HDC hdc_) { 132 import windows : PIXELFORMATDESCRIPTOR, ChoosePixelFormat, SetPixelFormat, PFD_DRAW_TO_WINDOW, PFD_SUPPORT_OPENGL, PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, PFD_MAIN_PLANE; 133 PIXELFORMATDESCRIPTOR pfd = PIXELFORMATDESCRIPTOR( 134 PIXELFORMATDESCRIPTOR.sizeof, 135 1, // version number 136 PFD_DRAW_TO_WINDOW | // support window 137 PFD_SUPPORT_OPENGL | // support OpenGL 138 PFD_DOUBLEBUFFER, // double buffered 139 PFD_TYPE_RGBA, // RGBA type 140 24, // 24-bit color depth 141 0, 0, 0, 0, 0, 0, // color bits ignored 142 0, // no alpha buffer 143 0, // shift bit ignored 144 0, // no accumulation buffer 145 0, 0, 0, 0, // accum bits ignored 146 32, // 32-bit z-buffer 147 8, // 8-bit stencil buffer 148 0, // no auxiliary buffer 149 PFD_MAIN_PLANE, // main layer 150 0, // reserved 151 0, 0, 0 // layer masks ignored 152 ); 153 154 int iPixelFormat; 155 156 // get the best available match of pixel format for the device context 157 iPixelFormat = ChoosePixelFormat(hdc_, &pfd); 158 159 // make that the pixel format of the device context 160 SetPixelFormat(hdc_, iPixelFormat, &pfd); 161 } 162 }